#include "GameOpt.h"
#include "Human.h"
#include "Entity.h"


Human::Human(const char inToken,Point DesPos)
:Entity(inToken,DesPos)
{
#ifdef DBG //on debug mode- automatic enter the players
	static int PlayersC= 0;
	if(PlayersC%4==0)
	{
		uiMaxMovement+=PERESENT_TYPE_MOVMENT_MAX_I*10;
		uiMaxHealth+=PERESENT_TYPE_HEALTH_I;
		uiDefense+=PERESENT_TYPE_DEFENCE_I*5;
		uiPower+=PERESENT_TYPE_POWER_I*10;
		uiMovement = uiMaxMovement;
		uiHealth= uiMaxHealth;

		uiExperience = 0;
		uiLevel = 1;
		strName = "Matan";
		PlayersC++;
	}
	else if(PlayersC%4==1)
	{
		cToken =inToken;
		uiMaxMovement+=PERESENT_TYPE_MOVMENT_MAX_I*10;
		uiMaxHealth+=PERESENT_TYPE_HEALTH_I;
		uiDefense+=PERESENT_TYPE_DEFENCE_I*10;
		uiPower+=PERESENT_TYPE_POWER_I*5;
		uiMovement = uiMaxMovement;
		uiHealth= uiMaxHealth;

		uiExperience = 0;
		uiLevel = 1;
		strName = "Dror";
		PlayersC++;
	}
	else if(PlayersC%4==2)
	{
		cToken =inToken;
		uiMaxMovement+=PERESENT_TYPE_MOVMENT_MAX_I*10;
		uiMaxHealth+=PERESENT_TYPE_HEALTH_I;
		uiDefense+=PERESENT_TYPE_DEFENCE_I;
		uiPower+=PERESENT_TYPE_POWER_I;
		uiMovement = uiMaxMovement;
		uiHealth= uiMaxHealth;

		uiExperience = 0;
		uiLevel = 1;
		strName = "Miki";
		PlayersC++;
	}
	else if(PlayersC%4==3)
	{
		cToken =inToken;
		uiMaxMovement+=PERESENT_TYPE_MOVMENT_MAX_I*10;
		uiMaxHealth+=PERESENT_TYPE_HEALTH_I;
		uiDefense+=PERESENT_TYPE_DEFENCE_I;
		uiPower+=PERESENT_TYPE_POWER_I;
		uiMovement = uiMaxMovement;
		uiHealth= uiMaxHealth;

		uiExperience = 0;
		uiLevel = 1;
		strName = "Dani";
		PlayersC++;
	}
#else

	unsigned int UsedLevels=0;
	string inStr;

	system("CLS");
	do
	{
		cout <<"Enter Name for the Player (upto 10 chars): ";
		cin >> inStr;
	}while(inStr.length()>10 || inStr.length() == 0);
	strName = inStr;

	//adding basic properties to the Human
	uiMaxMovement+=PERESENT_TYPE_MOVMENT_MAX_I;
	uiMaxHealth+=PERESENT_TYPE_HEALTH_I;
	uiDefense+=PERESENT_TYPE_DEFENCE_I;
	uiPower+=PERESENT_TYPE_POWER_I;

	do //add the Human Properies upto the const 'START_LEVELS'
	{
		incProperty(START_LEVELS-UsedLevels);
		UsedLevels++;
	}while(UsedLevels < START_LEVELS); 

	uiMovement = uiMaxMovement;
	uiHealth= uiMaxHealth;

	uiExperience = 0;
	uiLevel = 1;
#endif

}

Human::~Human() //nothig to delete
{
}

void Human::incProperty(unsigned int iProp)
{
	char inCh;
	do
	{
		//print Msg to the Player
		system("CLS");
		cout <<strName << " You Have "<< iProp <<" more levels to use"<< endl
		 << "What property do you want to increase?" << endl
		 << "M - Movement + "<< PERESENT_TYPE_MOVMENT_MAX_I <<" ?  Current: " << uiMaxMovement << endl
		 << "P - Power    + "<< PERESENT_TYPE_POWER_I <<" ?  Current: " << uiPower << endl
		 << "D - Defense  + "<< PERESENT_TYPE_DEFENCE_I <<" ?  Current: " << uiDefense << endl
		 << "H - Health   + "<< PERESENT_TYPE_HEALTH_MAX_I <<" ?  Current: " << uiMaxHealth <<endl;
		inCh = wait4key();
		inCh = (char)toupper(inCh);
	}while(inCh != 'M' && inCh != 'P' &&inCh != 'H' &&inCh != 'D'); //if the input is valid, 

	*this+=inCh; //use the +=operator to inc the Human Property
}

char Human::kind() const
{
	return KIND_HUMAN;
}

string Human::getName() const
{
	return strName;
}

unsigned int Human::getExperience() const
{
	return uiExperience;
}

unsigned int Human::incExperience(unsigned int iExp)
{
	return uiExperience+=iExp;
}

unsigned int Human::getLevel() const
{
	return uiLevel;
}

unsigned int Human::incLevel(unsigned int iLevel)
{
	return uiLevel+=iLevel;
}



Point Human::reqMove(Maze & GameMaze) //use the arrow keys to req movement on the board
{
	Point pntNextPos;
	int x=Pos.x(),y=Pos.y();

	do
	{
		char cArrowKey='N';
		cArrowKey=getArrowKey();

		x=Pos.x(); y=Pos.y();
		switch (cArrowKey)
		{
		case 'U':
			y=y-1;
			break;
		case 'D':
			y=y+1;
			break;
		case 'L':
			x=x-1;
			break;
		case 'R':
			x=x+1;
			break;
		case 'S': //the player want to stay (Space)
			break;
		default:
			break;
		}
	}while (GameMaze(x,y).isWall()); //do again if not a valid move
	
	pntNextPos(x,y);
	return pntNextPos;
}


void Human::operator +=(char cPreset)
//using the +=operator to inc the Human Propery. 
//by getting char according to Const defined chars one of the Human Propertys is increased
{
	switch(cPreset)
	{
	case PERESENT_TYPE_HEALTH:	
		uiHealth+=PERESENT_TYPE_HEALTH_I;
		if(uiHealth>uiMaxHealth)
			uiHealth=uiMaxHealth;
	break;
	case PERESENT_TYPE_HEALTH_MAX:	
		uiMaxHealth+=PERESENT_TYPE_HEALTH_MAX_I;
	break;
	case PERESENT_TYPE_MOVMENT:	
		uiMovement+=PERESENT_TYPE_MOVMENT_I;
		if(uiMovement>uiMaxMovement)
			uiMovement=uiMaxMovement;
	break;
	case PERESENT_TYPE_MOVMENT_MAX:	
		uiMaxMovement+=PERESENT_TYPE_MOVMENT_MAX_I;
	break;
	case PERESENT_TYPE_POWER:	
		uiPower+=PERESENT_TYPE_POWER_I;
	break;
	case PERESENT_TYPE_DEFENCE:	
		uiDefense+=PERESENT_TYPE_DEFENCE_I;
	break;
	}
	//return *this;
}

bool Human::SaveState(ofstream & FileName)
{
	FileName.write( reinterpret_cast<char*>(&uiPower), sizeof(uiPower));
	FileName.write( reinterpret_cast<char*>(&uiDefense), sizeof(uiDefense));
	FileName.write( reinterpret_cast<char*>(&uiHealth), sizeof(uiHealth));
	FileName.write( reinterpret_cast<char*>(&uiMaxHealth), sizeof(uiMaxHealth));
	FileName.write( reinterpret_cast<char*>(&uiMovement), sizeof(uiMovement));
	FileName.write( reinterpret_cast<char*>(&uiMaxMovement), sizeof(uiMaxMovement));
	FileName.write( reinterpret_cast<char*>(&cToken), sizeof(cToken));
	FileName.write( reinterpret_cast<char*>(&Pos), sizeof(Pos));

	FileName.write( reinterpret_cast<char*>(&uiExperience), sizeof(uiExperience));
	FileName.write( reinterpret_cast<char*>(&uiLevel), sizeof(uiLevel));
	FileName.write( reinterpret_cast<char*>(&strName), sizeof(strName));
	return 1;
}

bool Human::LoadState(ifstream & FileName)
{
	FileName.read( reinterpret_cast<char*>(&uiPower), sizeof(uiPower));
	FileName.read( reinterpret_cast<char*>(&uiDefense), sizeof(uiDefense));
	FileName.read( reinterpret_cast<char*>(&uiHealth), sizeof(uiHealth));
	FileName.read( reinterpret_cast<char*>(&uiMaxHealth), sizeof(uiMaxHealth));
	FileName.read( reinterpret_cast<char*>(&uiMovement), sizeof(uiMovement));
	FileName.read( reinterpret_cast<char*>(&uiMaxMovement), sizeof(uiMaxMovement));
	FileName.read( reinterpret_cast<char*>(&cToken), sizeof(cToken));
	FileName.read( reinterpret_cast<char*>(&Pos), sizeof(Pos));

	FileName.read( reinterpret_cast<char*>(&uiExperience), sizeof(uiExperience));
	FileName.read( reinterpret_cast<char*>(&uiLevel), sizeof(uiLevel));
	FileName.read( reinterpret_cast<char*>(&strName), sizeof(strName));
	return 1;
}